package com.hlhj.funlike_business.activity;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps2d.AMap;
import com.amap.api.maps2d.CameraUpdateFactory;
import com.amap.api.maps2d.LocationSource;
import com.amap.api.maps2d.MapView;
import com.amap.api.maps2d.model.BitmapDescriptorFactory;
import com.amap.api.maps2d.model.CameraPosition;
import com.amap.api.maps2d.model.Circle;
import com.amap.api.maps2d.model.LatLng;
import com.amap.api.maps2d.model.Marker;
import com.amap.api.maps2d.model.MarkerOptions;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.hlhj.funlike_business.R;
import com.hlhj.funlike_business.activity.adapter.SearchResultAdapter;
import com.hlhj.funlike_business.presenter.MyMapPresenter;
import com.hlhj.funlike_business.views.MyMapView;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;

public class MyMapAty extends Activity implements AMap.OnMapLoadedListener, LocationSource, AMapLocationListener, PoiSearch.OnPoiSearchListener {
    private MapView map;
    private AMap aMap;
    private AMapLocationClient mlocationClient;
    private AMapLocationClientOption mLocationOption;
    private LatLonPoint searchLatlonPoint;
    private ListView listview;
    private TextView tv_local_search;
    private EditText filter_edit;
    private SearchResultAdapter searchResultAdapter;
    private List<PoiItem> resultData = new ArrayList<>();
    private Marker mLocMarker;
    private OnLocationChangedListener mListener;
    private PoiSearch poisearch;
    private LatLng checkinpoint, mlocation;
    private LatLonPoint centerpoint;
    private boolean mFirstFix = false;
    private String searchkey = "餐饮服务";
    private String searchcity = "成都市";
    private Circle mCircle;
    public static final String LOCATION_MARKER_FLAG = "mylocation";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.aty_map);
        map=findViewById(R.id.map);
        map.onCreate(savedInstanceState);
        initView();
        initData();
    }

    private void initView() {
        listview=findViewById(R.id.listview);
        tv_local_search=findViewById(R.id.tv_local_search);
        filter_edit=findViewById(R.id.filter_edit);

    }

    private void initData() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                || ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            //请求权限
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
        } else {

        }

        initmap();
        initListener();
    }

    private void initListener() {
        filter_edit.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                searchkey=charSequence.toString();
            }

            @Override
            public void afterTextChanged(Editable editable) {

            }
        });
        tv_local_search.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                doSearchQuery();
            }
        });
    }

    private void initmap() {
        init();
        //初始化定位
        initLocation();
        //开始定位
        startLocation();

        aMap.setOnCameraChangeListener(new AMap.OnCameraChangeListener() {

            @Override
            public void onCameraChange(CameraPosition cameraPosition) {
                if (mLocMarker != null) {
                    LatLng latLng = cameraPosition.target;
                    mLocMarker.setPosition(latLng);
                    centerpoint = new LatLonPoint(latLng.latitude, latLng.longitude);
                    doSearchQuery();
                }
            }

            @Override
            public void onCameraChangeFinish(CameraPosition cameraPosition) {
//                removeMarksFromMap();//移动结束的时候，先移除地图上Maker(除了处于地图中心的Maker)
//                requestMarksData(cameraPosition.target);

            }
        });

    }

    private void init() {
        if (aMap == null) {
            aMap = map.getMap();
            setUpMap();
        }
        aMap.getUiSettings().setZoomControlsEnabled(false);
        aMap.setOnMapLoadedListener(this);

        searchResultAdapter = new SearchResultAdapter(this);
        searchResultAdapter.setData(resultData);
        listview.setAdapter(searchResultAdapter);

        listview.setOnItemClickListener(onItemClickListener);
    }

    private void initLocation() {
        //初始化client
        mlocationClient = new AMapLocationClient(this.getApplicationContext());
        // 设置定位监听
        mlocationClient.setLocationListener(this);
    }

    private void startLocation() {
        //设置定位参数
        mlocationClient.setLocationOption(getOption());
        // 启动定位
        mlocationClient.startLocation();
    }

    private void setUpMap() {
        aMap.setLocationSource(this);// 设置定位监听
        aMap.getUiSettings().setMyLocationButtonEnabled(false);// 设置默认定位按钮是否显示
        aMap.setMyLocationEnabled(true);// 设置为true表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false
        // 设置定位的类型为定位模式 ，可以由定位、跟随或地图根据面向方向旋转几种
        aMap.setMyLocationType(AMap.MAP_TYPE_NORMAL);
    }

    /**
     * 列表点击监听
     */
    AdapterView.OnItemClickListener onItemClickListener = new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//            if (position != searchResultAdapter.getSelectedPosition()) {
            PoiItem poiItem = (PoiItem) searchResultAdapter.getItem(position);
            LatLng curLatlng = new LatLng(poiItem.getLatLonPoint().getLatitude(), poiItem.getLatLonPoint().getLongitude());
            aMap.moveCamera(CameraUpdateFactory.changeLatLng(curLatlng));
            searchResultAdapter.setSelectedPosition(position);
            searchResultAdapter.notifyDataSetChanged();
            Intent intent = new Intent();
            String address = poiItem.getCityName() + poiItem.getAdName() + poiItem.getTitle();
            intent.putExtra("address", address);
            setResult(1001, intent);
            finish();
        }
//        }
    };

    /**
     * 设置定位参数
     *
     * @return 定位参数类
     */
    private AMapLocationClientOption getOption() {
        AMapLocationClientOption mOption = new AMapLocationClientOption();
        mOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);//可选，设置定位模式，可选的模式有高精度、仅设备、仅网络。默认为高精度模式
        mOption.setHttpTimeOut(30000);//可选，设置网络请求超时时间。默认为30秒。在仅设备模式下无效
        mOption.setNeedAddress(true);//可选，设置是否返回逆地理地址信息。默认是true
        mOption.setLocationCacheEnable(false);//设置是否返回缓存中位置，默认是true
        mOption.setOnceLocation(true);//可选，设置是否单次定位。默认是false
        return mOption;
    }


    @Override
    protected void onResume() {
        super.onResume();
        map.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        map.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        map.onDestroy();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        map.onSaveInstanceState(outState);
    }

    @Override
    public void onMapLoaded() {

    }

    @Override
    public void activate(OnLocationChangedListener onLocationChangedListener) {
        mListener = onLocationChangedListener;
        if (mlocationClient == null) {
            mlocationClient = new AMapLocationClient(this);
            mLocationOption = new AMapLocationClientOption();
            //设置定位监听
            mlocationClient.setLocationListener(this);
            //设置为高精度定位模式
            mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
            //设置定位参数
            mlocationClient.setLocationOption(mLocationOption);
            // 此方法为每隔固定时间会发起一次定位请求，为了减少电量消耗或网络流量消耗，
            // 注意设置合适的定位时间的间隔（最小间隔支持为2000ms），并且在合适时间调用stopLocation()方法来取消定位请求
            // 在定位结束后，在合适的生命周期调用onDestroy()方法
            // 在单次定位情况下，定位无论成功与否，都无需调用stopLocation()方法移除请求，定位sdk内部会移除
            mlocationClient.startLocation();
        }
    }

    @Override
    public void deactivate() {
        mListener = null;
        if (mlocationClient != null) {
            mlocationClient.stopLocation();
            mlocationClient.onDestroy();
        }
        mlocationClient = null;
    }

    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        if (aMapLocation != null && aMapLocation.getErrorCode() == 0) {
            mlocation = new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude());
            centerpoint = new LatLonPoint(aMapLocation.getLatitude(), aMapLocation.getLongitude());
            searchLatlonPoint = new LatLonPoint(aMapLocation.getLatitude(), aMapLocation.getLongitude());
            checkinpoint = mlocation;
            searchResultAdapter.setSelectedPosition(0);

            searchcity = aMapLocation.getCity();
            if (!mFirstFix) {
                mFirstFix = true;
//                addCircle(mlocation, aMapLocation.getAccuracy());//添加定位精度圆
                addMarker(mlocation);//添加定位图标
                aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mlocation, 18));
                if (searchLatlonPoint != null) {
                    resultData.clear();
                    resultData.add(new PoiItem("ID", searchLatlonPoint, "我的位置", searchLatlonPoint.toString()));
                    doSearchQuery();
                    searchResultAdapter.notifyDataSetChanged();
                }
            } else {
                mCircle.setCenter(mlocation);
                mCircle.setRadius(aMapLocation.getAccuracy());
                mLocMarker.setPosition(mlocation);
                aMap.moveCamera(CameraUpdateFactory.changeLatLng(mlocation));
            }

            mLocMarker.setPosition(mlocation);
        } else {
            String errText = "定位失败," + aMapLocation.getErrorCode() + ": " + aMapLocation.getErrorInfo();
            Log.e("AmapErr", errText);
        }
    }

    /**
     * 搜索周边poi
     */
    private void doSearchQuery() {
        PoiSearch.Query query = new PoiSearch.Query(searchkey, "", searchcity);
        query.setPageSize(20);
        query.setPageNum(1);
        poisearch = new PoiSearch(this, query);
        poisearch.setOnPoiSearchListener(this);
        poisearch.setBound(new PoiSearch.SearchBound(centerpoint, 500, true));
        poisearch.searchPOIAsyn();
    }

    /**
     * 添加标记
     * @param latlng
     */
    private void addMarker(LatLng latlng) {
        if (mLocMarker != null) {
            return;
        }
        MarkerOptions options = new MarkerOptions();
        options.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.ic_location_red)));
        options.anchor(0.5f, 1f);
        options.position(latlng);
        mLocMarker = aMap.addMarker(options);
        mLocMarker.setTitle(LOCATION_MARKER_FLAG);
    }

    @Override
    public void onPoiSearched(PoiResult poiResult, int resultCode) {
        if (resultCode == AMapException.CODE_AMAP_SUCCESS) {
            if (null != resultData && resultData.size() > 0) {
                resultData.clear();
            }
            resultData.clear();
            if (poiResult != null && poiResult.getPois().size() > 0) {
                List<PoiItem> poiItems = poiResult.getPois();
                resultData.addAll(poiItems);
                searchResultAdapter.notifyDataSetChanged();
            } else {
                Toast.makeText(this, "无搜索结果", Toast.LENGTH_SHORT).show();
            }
        } else {
//            Toast.makeText(mContext, "搜索失败，错误 " + resultCode, Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onPoiItemSearched(PoiItem poiItem, int i) {

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case 1: {
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED
                        && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
                    // 权限被用户同意。
                    // 执形我们想要的操作
                } else {
                    // 权限被用户拒绝了。
                    //若是点击了拒绝和不再提醒
                    //关于shouldShowRequestPermissionRationale
                    // 1、当用户第一次被询问是否同意授权的时候，返回false
                    // 2、当之前用户被询问是否授权，点击了false,并且点击了不在询问（第一次询问不会出现“不再询问”的选项），
                    // 之后便会返回false
                    // 3、当用户被关闭了app的权限，该app不允许授权的时候，返回false
                    // 4、当用户上一次不同意授权，没有点击“不再询问”的时候，下一次返回true
                    if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION)
                            || !ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION)) {
                        //提示用户前往设置界面自己打开权限
                        Toast.makeText(this, "请前往设置界面打开权限", Toast.LENGTH_SHORT).show();
                        return;
                    }

                }
            }
        }
    }
}
